package org.xurui.sxl.protocol.command.impl;

import lombok.extern.slf4j.Slf4j;
import org.jetlinks.core.message.CommonDeviceMessage;
import org.jetlinks.core.message.DeviceMessage;
import org.jetlinks.core.message.codec.EncodedMessage;
import org.jetlinks.core.message.codec.FromDeviceMessageContext;
import org.jetlinks.core.message.function.FunctionInvokeMessage;
import org.jetlinks.core.message.function.FunctionInvokeMessageReply;
import org.jetlinks.core.message.function.FunctionParameter;
import org.xurui.sxl.protocol.cache.ConcurrentMapCache;
import org.xurui.sxl.protocol.command.CmdCodec;
import org.xurui.sxl.protocol.enums.CommandEnum;
import org.xurui.sxl.protocol.utils.BinaryUtils;
import org.xurui.sxl.protocol.utils.NumberUtils;
import org.xurui.sxl.protocol.utils.SxlMessageUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 短信发送
 */
@Slf4j
public class CmdCodec_SENDSMS implements CmdCodec {
    @Override
    public boolean supportsCmd(String cmd) {
        return CommandEnum.SENDSMS.name().equals(cmd);
    }

    @Override
    public boolean supportsRelayCmd() {
        return true;
    }

    @Override
    public List<DeviceMessage> parsePayload(String payload, FromDeviceMessageContext context) {
        //设备回复格式：*XX,YYYYYYYYYYYYYYY,V4,SENDSMS,seq,para,HHMMSS,S,latitude,D,longitude,G,speed,pdop,DDMMYY,tracker _status#
        //设备回复示例：*TE,2020916301,V4,HOMEMAC,130305,1,B4:0B:44:CA:D4:8A,130306,V,2234.3061,N,11351.6677,E,0.85,0.76,160819,FDFFFDFF#
        FunctionInvokeMessageReply report = FunctionInvokeMessageReply.create();
        String[] payloadArr = payload.replaceAll("\\*","").split(",");
        String deviceId = payloadArr[1];
        report.setDeviceId(deviceId);
        Object messageIdObj = ConcurrentMapCache.getInstance().getAndRemove(deviceId+"_"+CommandEnum.SENDSMS.name()+"_"+payloadArr[4]);
        String messageId = messageIdObj==null?null:messageIdObj.toString();
        if(messageId==null){
            messageId = deviceId+"_"+payloadArr[4];
        }

        report.setFunctionId(CommandEnum.SENDSMS.name());
        report.setMessageId(messageId);
        report.setTimestamp(System.currentTimeMillis());
        String para=payloadArr[5]+","+payloadArr[6]+","+payloadArr[7];

        Map<String, Object> properties = new HashMap<>();
        properties.put("para",para);
        properties.put("uptime",payloadArr[8]);
        properties.put("s",payloadArr[9]);
        properties.put("latitude",BinaryUtils.getWgs84LonLat(payloadArr[10],"lat"));
        properties.put("d",payloadArr[11]);
        properties.put("longitude",BinaryUtils.getWgs84LonLat(payloadArr[12],"lon"));
        properties.put("g",payloadArr[13]);
        properties.put("speed", NumberUtils.parseDouble(payloadArr[14]));
        properties.put("pdop",NumberUtils.parseDouble(payloadArr[15]));
        properties.put("upday", payloadArr[16]);
        String trackerStatusHex = payloadArr[17];


        Map<String,Object> trackerStatusMap = parseTrackerStatus(trackerStatusHex);
        properties.put("trackerstatus",trackerStatusMap);
        report.setOutput(properties);

        //TODO 更新状态
        return genDeviceMessage(report);
    }

    @Override
    public EncodedMessage encodeMessage(CommonDeviceMessage message, String zzs) {
        //平台下发消息
        //格式：*XX,YYYYYYYYYYYYYYY,SENDSMS,HHMMSS,smscontent,codeType,NUMBER#
        //例子：*TE,2020916301,SENDSMS,130305,KTvolte,1,10001#
        //     *TE,2020916301,SENDSMS,130305,DGVOLTE,1,10010#
        //     *TE,2020916301,SENDSMS,130305,KTVOLTE,1,10086#
        //参数说明：smscontent 短信内容；最大 150 个字节
        //参数说明：codeType 短信编码；1：英文 ascii 格式；2：unicode big-endian，内码的 ascii 格式。暂只支持英文短信。
        //参数说明：NUMBER 号码
        if(message instanceof FunctionInvokeMessage) {
            FunctionInvokeMessage m = (FunctionInvokeMessage) message;
            List<FunctionParameter> params = m.getInputs();
            Map<String, Object> paramsMap = params.stream()
                .collect(Collectors.toMap(FunctionParameter::getName, FunctionParameter::getValue));
            String smscontent="";
            if(paramsMap.get("smscontent")!=null && !paramsMap.get("smscontent").equals("")) {
                smscontent=paramsMap.get("smscontent").toString();
            }
            String codeType="";
            if(paramsMap.get("codeType")!=null && !paramsMap.get("codeType").equals("")) {
                codeType=paramsMap.get("codeType").toString();
            }
            String number="";
            if(paramsMap.get("number")!=null && !paramsMap.get("number").equals("")) {
                number=paramsMap.get("number").toString();
            }

            String time = SxlMessageUtils.getTimeHHMMSS();//DateFormatUtils.format(new Date(),"HHmmss");
            /*StringBuffer sb = new StringBuffer();
            sb.append("*");
            sb.append(zzs);//TODO 需要修改成根据设备动态加载
            sb.append(",");
            sb.append(message.getDeviceId());
            sb.append(",");
            sb.append(CommandEnum.SENDSMS.name());
            sb.append(",");
            sb.append(time);
            sb.append(",");
            sb.append(smscontent);
            sb.append(",");
            sb.append(codeType);
            sb.append(",");
            sb.append(number);
            sb.append("#");*/
            ConcurrentMapCache.getInstance().set(message.getDeviceId()+"_"+CommandEnum.SENDSMS.name()+"_"+time,message.getMessageId(),60*3*1000);
            //return EncodedMessage.simple(Unpooled.wrappedBuffer(sb.toString().getBytes()));

            return SxlMessageUtils.SxlCmd.getInstance()
                .appendAndAddSeparator(zzs)
                .appendAndAddSeparator(message.getDeviceId())
                .appendAndAddSeparator(CommandEnum.SENDSMS.name())
                .appendAndAddSeparator(time)
                .appendAndAddSeparator(smscontent)
                .appendAndAddSeparator(codeType)
                .append(number).buildEncodeMessage();
        }else{
            if (log.isDebugEnabled()) {
                log.debug("非FunctionInvokeMessage指令{}消息{}",CommandEnum.WIFISCAN.name(),message);
            }
            return null;
        }

    }
}
